package com.game.gateway.netty;

import com.game.framework.message.protobuf.GatewayProto;
import com.game.framework.message.protobuf.BaseProto;
import com.google.protobuf.ByteString;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.concurrent.GlobalEventExecutor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.Base64Utils;
import org.springframework.util.ObjectUtils;

@Slf4j
public class ClientNettyHandler extends ChannelInboundHandlerAdapter {
    public static final ChannelGroup clients = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        BaseProto.BaseReq baseReq = (BaseProto.BaseReq) msg;
        log.info("收到消息: " + baseReq.toString());

        if (baseReq.getMc().equals(BaseProto.MessageCode.MC_CONNECT)) {
            GatewayProto.ConnectRequest request = GatewayProto.ConnectRequest.parseFrom(baseReq.getBody());
            log.info("【MC_CONNECT】请求消息：" + request);
            String publicKey = request.getPublicKey();
            // 获取客户端的公钥字符串。
            //String aesSecretKey = AESUtil.createSecret();
            //byte[] clientPublicKey = Base64Utils.decodeFromString(publicKey);
            //byte[] encryptAesKey = RSAUtil.encryptByPublicKey(aesSecretKey.getBytes(), clientPublicKey);// 使用客户端的公钥加密对称加密密钥
            GatewayProto.ConnectResponse.Builder responseBuilder = GatewayProto.ConnectResponse.newBuilder();
            responseBuilder.setSecretKey(Base64Utils.encodeToString(publicKey.getBytes()));// 返回给客户端
            responseBuilder.setServerIp("39.103.162.3");
            responseBuilder.setServerPort(9877);
            if (!ObjectUtils.isEmpty(responseBuilder)) {
                ByteString resBody = responseBuilder.build().toByteString();
                receiveMessage(
                        BaseProto.MessageCode.MC_CONNECT,
                        BaseProto.ResStatus.STATUS_SUCCESS,
                        BaseProto.ErrorCode.SUCCESS,
                        resBody,
                        ctx);
            } else {
                receiveMessage(
                        BaseProto.MessageCode.MC_CONNECT,
                        BaseProto.ResStatus.STATUS_ERROR,
                        BaseProto.ErrorCode.UNKNOWN_ERROR,
                        ByteString.EMPTY,
                        ctx);
            }
            log.info("【MC_CONNECT】返回结果：" + responseBuilder);
        }

    }

    @Override
    public void handlerAdded(ChannelHandlerContext ctx) {
        log.info("新的客户端链接：" + ctx.channel().id().asShortText());
        clients.add(ctx.channel());
    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) {
        log.info("客户端断开链接：" + ctx.channel().id().asShortText());
        clients.remove(ctx.channel());
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        log.info("客户端发生错误：" + ctx.channel().id().asShortText() + "  " + cause.getMessage());
        ctx.channel().close();
        clients.remove(ctx.channel());
    }

    private void receiveMessage(BaseProto.MessageCode mc, BaseProto.ResStatus status, BaseProto.ErrorCode errorCode, ByteString body, ChannelHandlerContext ctx) {
        BaseProto.BaseRes baseRes = BaseProto.BaseRes.newBuilder()
                .setMc(mc)
                .setStatus(status)
                .setCode(errorCode)
                //.setMsg(errorCode.getErrorMessage())
                .setBody(body).build();
        ByteBuf response = Unpooled.copiedBuffer(baseRes.toByteArray());
        ctx.writeAndFlush(response);
    }
}